package com.sxj.corejava.code05_反射;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author 石小俊
 * @date 2023年12月2023/12/21日 18:47
 */
public class Test05_操作方法 {

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class c = User.class;

        // 1.获取当前类以及其祖先类中所有public修饰的方法
        Method[] methods = c.getMethods();
        for(Method method : methods){
            System.out.println(method);
        }
        System.out.println("-----------------------------------");
        // 2.获取当前类中的所有方法,不区分修饰符
        methods = c.getDeclaredMethods();
        for(Method method : methods){
            System.out.println(method);
        }
        System.out.println("-----------------------------------");
        // 3.获取当前类以及其祖先类中public修饰的指定方法
        // 由于方法存在重载,因此必须指定参数的类型
        // 当前类的
        Method addMethod = c.getMethod("add",int.class,int.class);
        System.out.println(addMethod);
        addMethod = c.getMethod("add",double.class,double.class);
        System.out.println(addMethod);

        // 父类的
        Method sayHello = c.getMethod("sayHello");
        System.out.println(sayHello);

        // 4.获取当前类中的指定方法,不区分修饰符
        addMethod = c.getDeclaredMethod("add",double.class,double.class);
        System.out.println(addMethod);
        Method showMethod = c.getDeclaredMethod("show");
        System.out.println(showMethod);

//        sayHello = c.getDeclaredMethod("sayHello");
//        System.out.println(sayHello);

        // 获取方法名
        System.out.println("showMethod方法名:"+showMethod.getName());
        System.out.println("-----------------------------------");

        // 通过invoke(Object obj, Object... args)执行方法
        // 参数一:表示调用的方法是哪个对象的方法
        // 参数二:方法的实际参数
        User user = new User();
        Object result = addMethod.invoke(user,2, 3);
        System.out.println(result);

        Method testMethod = c.getDeclaredMethod("test");
        testMethod.invoke(user);

        // 无法直接访问private修饰的方法
        // 同样可以取消权限控制检查,即:破坏封装原则
        showMethod.setAccessible(true);
        showMethod.invoke(user);
    }

}
